package com.engine.ld.optimize;

import com.engine.core.exception.ECException;
import com.weaver.general.BaseBean;
import com.weaver.general.Util;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import weaver.conn.RecordSet;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;

/**
 * @author ZhangLei
 * @date 2021/6/25
 */
public class Gyszsj {
    private static final BaseBean bb = new BaseBean();
//    新建
    public  String createGyszsj(String requestid) throws ParserConfigurationException {
        bb.writeLog("供应商主数据新建流程");

        String[] groupParams = {"KTOKK","LIFNR","TITLE","NAME1","NAME2","NAME3","NAME4","SORT1",
                "SORT2","STRAS","HOUSE_NUM1","POST_CODE1","CITY1","COUNTRY","REGION","TIME_ZONE",
                "LANGU","TELF1","TELF2","FAX_NUMBER","SMTP_ADDR","BANKS","BANKL","BANKA","BANKN","IBAN",
                "ZFLAG","LOEVM","KUNNR"};

        String[] companyParams = {"LIFNRGSDMC","BUKRS","AKONT","ZUAWA","ZTERM","TOGRU","REPRF","ZWELS","TOGRR",
                "LOEVMGSDM","ZFLAGGSDM"};
//        注意LOEVMGSDM,ZFLAGGSDM字段在转xml时字段需要分别存为LOEVM，ZFLAG

        String[] saleParams = {"LIFNRCGZZC","EKORG","WAERS","ZTERM","INCO1","INCO2","VERKF","XTELF1","WEBRE",
                "BOLRE","EKGRP","LOEVMCGZZ","ZFLAGCGZZ"};
//        注意XTELF1、LOEVMCGZZ、ZFLAGCGZZ转xml时分别存为TELF1、LOEVM、ZFLAG

        String tableName = "formtable_main_109";
//        查询GROUP子节点所需要的数据
        Map<String, Object> selectGroup = select(groupParams, tableName, requestid);
//        查询Company子节点所需要的数据
        Map<String, Object> selectCompany = select(companyParams, tableName, requestid);
//        查询sale自己的点所需要的数据
        Map<String, Object> selectSale = select(saleParams, tableName, requestid);

//        组装XMl并返回
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.newDocument();
        Element root = document.createElement("ROOT");
        document.appendChild(root);
//        创建GROUP节点以及子节点，并赋值
        Element group = document.createElement("GROUP");
        for (String groupParam : groupParams) {
            if ("LANGU".equals(groupParam)){
                appendChild(document,group,"LANGU", Util.null2String(selectGroup.get(groupParam).toString()).equals("ZH") ?"1":"2");
            }else {
                appendChild(document,group,groupParam,Util.null2String(selectGroup.get(groupParam).toString()));
            }

        }
        root.appendChild(group);
//        创建COMPANY节点以及子节点并赋值
        Element company = document.createElement("COMPANY");
        for (String companyParam : companyParams) {
            if ("LOEVMGSDM".equals(companyParam)){
                appendChild(document,company,"LOEVM",Util.null2String(selectCompany.get(companyParam).toString()));
            }else if ("ZFLAGGSDM".equals(companyParam)){
                appendChild(document,company,"ZFLAG",Util.null2String(selectCompany.get(companyParam).toString()));
            }else if ("REPRF".equals(companyParam)){
                appendChild(document,company,"REPRF","X");
            }else if ("LIFNRGSDMC".equals(companyParam)){
                appendChild(document,company,"LIFNR",Util.null2String(selectCompany.get(companyParam).toString()));
            }else {
                appendChild(document,company,companyParam,Util.null2String(selectCompany.get(companyParam).toString()));
            }
        }
        root.appendChild(company);

//        创建SALE节点以及子节点并赋值
        Element sale = document.createElement("SALE");
        for (String saleParam : saleParams) {
//            XTELF1、LOEVMCGZZ、ZFLAGCGZZ转xml时分别存为TELF1、LOEVM、ZFLAG
            if ("XTELF1".equals(saleParam)){
                appendChild(document,sale,"TELF1",Util.null2String(selectSale.get(saleParam).toString()));
            }else if ("LOEVMCGZZ".equals(saleParam)){
                appendChild(document,sale,"LOEVM",Util.null2String(selectSale.get(saleParam).toString()));
            }else if ("ZFLAGCGZZ".equals(saleParam)){
                if ("3".equals(selectSale.get(saleParam).toString())){
                    appendChild(document,sale,"ZFLAG","2");
                }else {
                    appendChild(document,sale,"ZFLAG",Util.null2String(selectSale.get(saleParam).toString()));
                }
            }else if ("WEBRE".equals(saleParam)){
                appendChild(document,sale,"WEBRE","X");
            }else if ("LIFNRCGZZC".equals(saleParam)){
                appendChild(document,sale,"LIFNR",Util.null2String(selectSale.get(saleParam).toString()));
            }
            else {
                appendChild(document,sale,saleParam,Util.null2String(selectSale.get(saleParam).toString()));
            }
        }
        //        WEBRE节点添加，默认X

        root.appendChild(sale);

        bb.writeLog("result: " + createXmlToString(document));


        return createXmlToString(document);
    }
//    修改
    public  void updateGyszsj(String requestid,String xmlResult){
        bb.writeLog("请求返回的xmlResult：" + xmlResult);
        String updateSql = "update formtable_main_109 set TYPE = ?, MESSAGE = ? where requestid = ?";
        if(xmlResult == null || "".equals(xmlResult) || requestid == null || "".equals(requestid)) {
            throw new ECException("参数不全");
        }

        xmlResult = trimXmlStr(xmlResult);
        Document document;
        try {
            document = strToDocument(xmlResult);
        } catch(Exception e) {
            bb.writeLog("XML解析失败: " + e.getMessage());
            bb.writeLog("xmlResult: " + xmlResult);
            throw new ECException("XML解析失败: " + e.getMessage());
        }

        Element root = document.getDocumentElement();
        NodeList typeNodeList = root.getElementsByTagName("TYPE");
        NodeList messageNodeList = root.getElementsByTagName("MESSAGE");

        if(typeNodeList.getLength() > 0 && messageNodeList.getLength() > 0) {
            String type = Util.null2String(typeNodeList.item(0).getTextContent());
            String message = Util.null2String(messageNodeList.item(0).getTextContent());
            bb.writeLog("type: " + type);
            bb.writeLog("message : " + message);
            RecordSet rs = new RecordSet();
            rs.executeUpdate(updateSql, type, message, requestid);
        } else {
            bb.writeLog("未获取到正常返回数据");
            bb.writeLog("xmlResult: " + xmlResult);
            throw new ECException("未获取到正常返回数据");
        }
    }


    /*
    * 入参：
    *       1、String[]:记录要查哪些字段
    *       2、查询的表名
    *       3、where条件(requestId)
    * 出参：Map<String,Object>:记录根据入参查询的结果
    * 以应对需要分组返回xml时的情况
    * */
    private static Map<String,Object> select(String[] params, String tableName, String selectWhere){
        Map<String,Object> resultMap = new HashMap<>();
//        组装xml
        StringBuilder sql = new StringBuilder("SELECT ");
        for (int i = 0; i < params.length; i++) {
            if (i == params.length-1){
                sql.append(params[i]).append(" from ");
            }else if (!"REPRF".equals(params[i]) && !"WEBRE".equals(params[i])){
                sql.append(params[i]).append(',');
            }
        }
        sql.append(tableName).append(" WHERE REQUESTID = ").append(selectWhere);

//        查询
        RecordSet rs = new RecordSet();
        rs.executeQuery(sql.toString());
        if (rs.next()){
            for (String param : params) {
                resultMap.put(param, Util.null2String(rs.getString(param)));
            }
        }
        return resultMap;
    }


    /**
     * xml固定头部
     */
    private static String xmlHeadStr() {
        return "<asx:abap version=\"1.0\" xmlns:asx=\"http://www.sap.com/abapxml\">\n" +
                "\t<asx:values>\n" +
                "\t\t<_--5CTYPE_--3DSTRING>\n";
    }

    /**
     * xml固定尾部
     */
    private static String xmlTailStr() {
        return "\t\t</_--5CTYPE_--3DSTRING>\n" +
                "\t</asx:values>\n" +
                "</asx:abap>";
    }

    /**
     * 生成xml字符串
     * @param document Document树对象
     * @return 整个xml字符串
     */
    private static String createXmlToString(Document document){
        String xmlString = null;
        try {
            // 创建TransformerFactory工厂对象
            TransformerFactory transFactory = TransformerFactory.newInstance();
            // 通过工厂对象, 创建Transformer对象
            Transformer transformer = transFactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.ENCODING, "GBK");
            //使Xml自动换行, 并自动缩进
            transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "");
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");  //中间的参数网址固定写法(这里还没搞懂)
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");                          //是否设置缩进（indent: yes|no）
            // 创建DOMSource对象并将Document加载到其中
            DOMSource domSource = new DOMSource(document);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            // 使用Transformer的transform()方法将DOM树转换成XML
            transformer.transform(domSource, new StreamResult(bos));
            xmlString = bos.toString();
        } catch (TransformerException e) {
            e.printStackTrace();
        }
        return xmlString;
    }

    /**
     * document对象中添加子项
     * @param document ducument对象
     * @param parent 父元素
     * @param key 元素标签
     * @param value 元素content值
     */
    private static void appendChild(Document document, Element parent, String key, String value) {
        Element child = document.createElement(key);
        if(child != null) {
            child.setTextContent(value);
        }
        parent.appendChild(child);
    }

    /**
     * 去除<_--5CTYPE_--3DSTRING>之前部分，去除</_--5CTYPE_--3DSTRING>之后部分
     * @param xmlString xml字符串
     * @return 去除头尾部分的xml字符串
     */
    private static String trimXmlStr(String xmlString) {
        if(!xmlString.contains("<_--5CTYPE_--3DSTRING>")) {
            return xmlString;
        }
        int start = xmlString.indexOf("<_--5CTYPE_--3DSTRING>") + "<_--5CTYPE_--3DSTRING>".length();
        int end = xmlString.indexOf("</_--5CTYPE_--3DSTRING>");
        return xmlString.substring(start, end).trim();
    }

    /**
     * 将字符串转为xmldom对象
     * @param xmlString xml字符串
     * @return dom对象
     * @throws ParserConfigurationException 创建document对象异常
     * @throws IOException IO异常
     * @throws SAXException 解析异常
     */
    private static Document strToDocument(String xmlString) throws ParserConfigurationException, IOException, SAXException {

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
        return documentBuilder.parse(
                new InputSource(new StringReader(xmlString)));
    }


}
